<!DOCTYPE html>
<html lang="zh-CN">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta name="robots" content="noodp" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1">
        <title>react扩展 - 肉蛋葱鸡肉粥🍛的博客☕</title><meta name="Description" content=""><meta property="og:title" content="react扩展" />
<meta property="og:description" content="1. setState setState更新状态的2种写法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 (1). setState(stateChange, [callback])------对象式的setState 1.sta" />
<meta property="og:type" content="article" />
<meta property="og:url" content="http://example.org/posts/react%E6%89%A9%E5%B1%95/" /><meta property="article:section" content="posts" />
<meta property="article:published_time" content="2021-09-02T10:42:53+08:00" />
<meta property="article:modified_time" content="2021-09-02T10:42:53+08:00" /><meta property="og:site_name" content="肉蛋葱鸡肉粥🍛的博客☕" />

<meta name="twitter:card" content="summary"/>
<meta name="twitter:title" content="react扩展"/>
<meta name="twitter:description" content="1. setState setState更新状态的2种写法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 (1). setState(stateChange, [callback])------对象式的setState 1.sta"/>
<meta name="application-name" content="肉蛋葱鸡肉粥🍛的博客☕">
<meta name="apple-mobile-web-app-title" content="肉蛋葱鸡肉粥🍛的博客☕"><link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />
        <link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
        <link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png"><link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png"><link rel="manifest" href="/site.webmanifest"><link rel="canonical" href="http://example.org/posts/react%E6%89%A9%E5%B1%95/" /><link rel="prev" href="http://example.org/posts/reacthooks/" /><link rel="next" href="http://example.org/posts/first_post/" /><link rel="stylesheet" href="/lib/normalize/normalize.min.css"><link rel="stylesheet" href="/css/style.min.css"><link rel="stylesheet" href="/lib/fontawesome-free/all.min.css"><link rel="stylesheet" href="/lib/animate/animate.min.css"><script type="application/ld+json">
    {
        "@context": "http://schema.org",
        "@type": "BlogPosting",
        "headline": "react扩展",
        "inLanguage": "zh-CN",
        "mainEntityOfPage": {
            "@type": "WebPage",
            "@id": "http:\/\/example.org\/posts\/react%E6%89%A9%E5%B1%95\/"
        },"genre": "posts","keywords": "react, react优化","wordcount":  2636 ,
        "url": "http:\/\/example.org\/posts\/react%E6%89%A9%E5%B1%95\/","datePublished": "2021-09-02T10:42:53+08:00","dateModified": "2021-09-02T10:42:53+08:00","publisher": {
            "@type": "Organization",
            "name": "yzuxqz"},"author": {
                "@type": "Person",
                "name": "yzuxqz"
            },"description": ""
    }
    </script></head>
    <body header-desktop="" header-mobile=""><script type="text/javascript">(window.localStorage && localStorage.getItem('theme') ? localStorage.getItem('theme') === 'dark' : ('' === 'auto' ? window.matchMedia('(prefers-color-scheme: dark)').matches : '' === 'dark')) && document.body.setAttribute('theme', 'dark');</script>

        <div id="mask"></div><div class="wrapper"><header class="desktop" id="header-desktop">
    <div class="header-wrapper">
        <div class="header-title">
            <a href="/" title="肉蛋葱鸡肉粥🍛的博客☕">肉蛋葱鸡肉粥🍛的博客☕</a>
        </div>
        <div class="menu">
            <div class="menu-inner"><a class="menu-item" href="/posts/"> 文章 </a><a class="menu-item" href="/tags/"> 标签 </a><a class="menu-item" href="/categories/"> 分类 </a><a class="menu-item" href="/about/"> 关于 </a><span class="menu-item delimiter"></span><a href="javascript:void(0);" class="menu-item language" title="选择语言">简体中文<i class="fas fa-chevron-right fa-fw"></i>
                        <select class="language-select" id="language-select-desktop" onchange="location = this.value;"><option value="/posts/react%E6%89%A9%E5%B1%95/" selected>简体中文</option></select>
                    </a><a href="javascript:void(0);" class="menu-item theme-switch" title="切换主题">
                    <i class="fas fa-adjust fa-fw"></i>
                </a>
            </div>
        </div>
    </div>
</header><header class="mobile" id="header-mobile">
    <div class="header-container">
        <div class="header-wrapper">
            <div class="header-title">
                <a href="/" title="肉蛋葱鸡肉粥🍛的博客☕">肉蛋葱鸡肉粥🍛的博客☕</a>
            </div>
            <div class="menu-toggle" id="menu-toggle-mobile">
                <span></span><span></span><span></span>
            </div>
        </div>
        <div class="menu" id="menu-mobile"><a class="menu-item" href="/posts/" title="">文章</a><a class="menu-item" href="/tags/" title="">标签</a><a class="menu-item" href="/categories/" title="">分类</a><a class="menu-item" href="/about/" title="">关于</a><a href="javascript:void(0);" class="menu-item theme-switch" title="切换主题">
                <i class="fas fa-adjust fa-fw"></i>
            </a><a href="javascript:void(0);" class="menu-item" title="选择语言">简体中文<i class="fas fa-chevron-right fa-fw"></i>
                    <select class="language-select" onchange="location = this.value;"><option value="/posts/react%E6%89%A9%E5%B1%95/" selected>简体中文</option></select>
                </a></div>
    </div>
</header>
<div class="search-dropdown desktop">
    <div id="search-dropdown-desktop"></div>
</div>
<div class="search-dropdown mobile">
    <div id="search-dropdown-mobile"></div>
</div>
<main class="main">
                <div class="container"><div class="toc" id="toc-auto">
            <h2 class="toc-title">目录</h2>
            <div class="toc-content" id="toc-content-auto"></div>
        </div><article class="page single"><h1 class="single-title animated flipInX">react扩展</h1><div class="post-meta">
            <div class="post-meta-line"><span class="post-author"><a href="https://github.com/yzuxqz" title="Author" target="_blank" rel="noopener noreffer author" class="author"><i class="fas fa-user-circle fa-fw"></i>yzuxqz</a></span>&nbsp;<span class="post-category">收录于 <a href="/categories/react/"><i class="far fa-folder fa-fw"></i>react</a>&nbsp;<a href="/categories/%E5%89%8D%E7%AB%AF/"><i class="far fa-folder fa-fw"></i>前端</a></span></div>
            <div class="post-meta-line"><i class="far fa-calendar-alt fa-fw"></i>&nbsp;<time datetime="2021-09-02">2021-09-02</time>&nbsp;<i class="fas fa-pencil-alt fa-fw"></i>&nbsp;约 2636 字&nbsp;
                <i class="far fa-clock fa-fw"></i>&nbsp;预计阅读 6 分钟&nbsp;</div>
        </div><div class="details toc" id="toc-static"  kept="">
                <div class="details-summary toc-title">
                    <span>目录</span>
                    <span><i class="details-icon fas fa-angle-right"></i></span>
                </div>
                <div class="details-content toc-content" id="toc-content-static"><nav id="TableOfContents">
  <ul>
    <li><a href="#1-setstate">1. setState</a>
      <ul>
        <li><a href="#setstate更新状态的2种写法">setState更新状态的2种写法</a></li>
      </ul>
    </li>
    <li><a href="#2-lazyload">2. lazyLoad</a>
      <ul>
        <li><a href="#路由组件的lazyload">路由组件的lazyLoad</a></li>
      </ul>
    </li>
    <li><a href="#3-hooks">3. Hooks</a>
      <ul>
        <li>
          <ul>
            <li><a href="#1-react-hookhooks是什么">1. React Hook/Hooks是什么?</a></li>
            <li><a href="#2-三个常用的hook">2. 三个常用的Hook</a></li>
            <li><a href="#3-state-hook">3. State Hook</a></li>
            <li><a href="#4-effect-hook">4. Effect Hook</a></li>
            <li><a href="#5-ref-hook">5. Ref Hook</a></li>
          </ul>
        </li>
      </ul>
    </li>
    <li><a href="#4-fragment">4. Fragment</a>
      <ul>
        <li><a href="#使用">使用</a></li>
        <li><a href="#作用">作用</a></li>
      </ul>
    </li>
    <li><a href="#5-context">5. Context</a>
      <ul>
        <li><a href="#理解">理解</a></li>
        <li><a href="#使用-1">使用</a></li>
        <li><a href="#注意">注意</a></li>
      </ul>
    </li>
    <li><a href="#6-组件优化">6. 组件优化</a>
      <ul>
        <li><a href="#component的2个问题">Component的2个问题</a></li>
        <li><a href="#效率高的做法">效率高的做法</a></li>
        <li><a href="#原因">原因</a></li>
        <li><a href="#解决">解决</a></li>
      </ul>
    </li>
    <li><a href="#7-render-props">7. render props</a>
      <ul>
        <li><a href="#如何向组件内部动态传入带内容的结构标签">如何向组件内部动态传入带内容的结构(标签)?</a></li>
        <li><a href="#children-props">children props</a></li>
        <li><a href="#render-props">render props</a></li>
      </ul>
    </li>
    <li><a href="#8-错误边界">8. 错误边界</a>
      <ul>
        <li>
          <ul>
            <li><a href="#理解-1">理解：</a></li>
            <li><a href="#特点">特点：</a>
              <ul>
                <li><a href="#使用方式">使用方式：</a></li>
              </ul>
            </li>
          </ul>
        </li>
      </ul>
    </li>
    <li><a href="#9-组件通信方式总结">9. 组件通信方式总结</a>
      <ul>
        <li>
          <ul>
            <li><a href="#组件间的关系">组件间的关系：</a></li>
            <li><a href="#几种通信方式">几种通信方式：</a></li>
            <li><a href="#比较好的搭配方式">比较好的搭配方式：</a></li>
          </ul>
        </li>
      </ul>
    </li>
  </ul>
</nav></div>
            </div><div class="content" id="content"><h2 id="1-setstate">1. setState</h2>
<h3 id="setstate更新状态的2种写法">setState更新状态的2种写法</h3>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback">	(1). setState(stateChange, [callback])------对象式的setState
            1.stateChange为状态改变对象(该对象可以体现出状态的更改)
            2.callback是可选的回调函数, 它在状态更新完毕、界面也更新后(render调用后)才被调用
					
	(2). setState(updater, [callback])------函数式的setState
            1.updater为返回stateChange对象的函数。
            2.updater可以接收到state和props。
            4.callback是可选的回调函数, 它在状态更新、界面也更新后(render调用后)才被调用。
总结:
		1.对象式的setState是函数式的setState的简写方式(语法糖)
		2.使用原则：
				(1).如果新状态不依赖于原状态 ===&gt; 使用对象方式
				(2).如果新状态依赖于原状态 ===&gt; 使用函数方式
				(3).如果需要在setState()执行后获取最新的状态数据, 
					要在第二个callback函数中读取
</code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span><span class="lnt">9
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="c1">//第二种 , 有两种写法 区别在于括号
</span><span class="c1"></span><span class="k">this</span><span class="p">.</span><span class="nx">setState</span><span class="p">((</span><span class="nx">preState</span><span class="p">,</span> <span class="nx">props</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span>
                    <span class="k">return</span> <span class="p">{</span><span class="nx">isAuthenticated</span><span class="o">:</span> <span class="nx">props</span><span class="p">.</span><span class="nx">isAuthen</span><span class="p">}</span>
                <span class="p">});</span>
                
<span class="k">this</span><span class="p">.</span><span class="nx">setState</span><span class="p">((</span><span class="nx">preState</span><span class="p">,</span> <span class="nx">props</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">({</span>
                    <span class="nx">isAuthenticated</span><span class="o">:</span> <span class="o">!</span><span class="nx">preState</span><span class="p">.</span><span class="nx">isAuthenticated</span>
                <span class="p">}));</span>

</code></pre></td></tr></table>
</div>
</div><hr>
<h2 id="2-lazyload">2. lazyLoad</h2>
<h3 id="路由组件的lazyload">路由组件的lazyLoad</h3>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-js" data-lang="js">	<span class="c1">//1.通过React的lazy函数配合import()函数动态加载路由组件 ===&gt; 路由组件代码会被分开打包
</span><span class="c1"></span>	<span class="kr">const</span> <span class="nx">Login</span> <span class="o">=</span> <span class="nx">lazy</span><span class="p">(()=&gt;</span><span class="kr">import</span><span class="p">(</span><span class="s1">&#39;@/pages/Login&#39;</span><span class="p">))</span>
	
	<span class="c1">//2.通过&lt;Suspense&gt;指定在加载得到路由打包文件前显示一个自定义loading界面
</span><span class="c1"></span>	<span class="o">&lt;</span><span class="nx">Suspense</span> <span class="nx">fallback</span><span class="o">=</span><span class="p">{</span><span class="o">&lt;</span><span class="nx">h1</span><span class="o">&gt;</span><span class="nx">loading</span><span class="p">.....</span><span class="o">&lt;</span><span class="err">/h1&gt;}&gt;</span>
        <span class="o">&lt;</span><span class="nx">Switch</span><span class="o">&gt;</span>
            <span class="o">&lt;</span><span class="nx">Route</span> <span class="nx">path</span><span class="o">=</span><span class="s2">&#34;/xxx&#34;</span> <span class="nx">component</span><span class="o">=</span><span class="p">{</span><span class="nx">Xxxx</span><span class="p">}</span><span class="o">/&gt;</span>
            <span class="o">&lt;</span><span class="nx">Redirect</span> <span class="nx">to</span><span class="o">=</span><span class="s2">&#34;/login&#34;</span><span class="o">/&gt;</span>
        <span class="o">&lt;</span><span class="err">/Switch&gt;</span>
    <span class="o">&lt;</span><span class="err">/Suspense&gt;</span>
</code></pre></td></tr></table>
</div>
</div><hr>
<h2 id="3-hooks">3. Hooks</h2>
<h4 id="1-react-hookhooks是什么">1. React Hook/Hooks是什么?</h4>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback">(1). Hook是React 16.8.0版本增加的新特性/新语法
(2). 可以让你在函数组件中使用 state 以及其他的 React 特性
</code></pre></td></tr></table>
</div>
</div><h4 id="2-三个常用的hook">2. 三个常用的Hook</h4>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback">(1). State Hook: React.useState()
(2). Effect Hook: React.useEffect()
(3). Ref Hook: React.useRef()
</code></pre></td></tr></table>
</div>
</div><h4 id="3-state-hook">3. State Hook</h4>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback">(1). State Hook让函数组件也可以有state状态, 并进行状态数据的读写操作
(2). 语法: const [xxx, setXxx] = React.useState(initValue)  
(3). useState()说明:
        参数: 第一次初始化指定的值在内部作缓存
        返回值: 包含2个元素的数组, 第1个为内部当前状态值, 第2个为更新状态值的函数
(4). setXxx()2种写法:
        setXxx(newValue): 参数为非函数值, 直接指定新的状态值, 内部用其覆盖原来的状态值
        setXxx(value =&gt; newValue): 参数为函数, 接收原本的状态值, 返回新的状态值, 内部用其覆盖原来的状态值
</code></pre></td></tr></table>
</div>
</div><h4 id="4-effect-hook">4. Effect Hook</h4>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback">(1). Effect Hook 可以让你在函数组件中执行副作用操作(用于模拟类组件中的生命周期钩子)
(2). React中的副作用操作:
        发ajax请求数据获取
        设置订阅 / 启动定时器
        手动更改真实DOM
(3). 语法和说明: 
        useEffect(() =&gt; { 
          // 在此可以执行任何带副作用操作
          return () =&gt; { // 在组件卸载前执行
            // 在此做一些收尾工作, 比如清除定时器/取消订阅等
          }
        }, [stateValue]) // 如果指定的是[], 回调函数只会在第一次render()后执行
    
(4). 可以把 useEffect Hook 看做如下三个函数的组合
        componentDidMount()
        componentDidUpdate()
    	componentWillUnmount() 
</code></pre></td></tr></table>
</div>
</div><h4 id="5-ref-hook">5. Ref Hook</h4>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback">(1). Ref Hook可以在函数组件中存储/查找组件内的标签或任意其它数据
(2). 语法: const refContainer = useRef()
(3). 作用:保存标签对象,功能与React.createRef()一样
</code></pre></td></tr></table>
</div>
</div><hr>
<h2 id="4-fragment">4. Fragment</h2>
<h3 id="使用">使用</h3>
<pre><code>&lt;Fragment&gt;&lt;Fragment&gt;
&lt;&gt;&lt;/&gt;
</code></pre>
<h3 id="作用">作用</h3>
<blockquote>
<p>可以不用必须有一个真实的DOM根标签了</p>
</blockquote>
<hr/>
<h2 id="5-context">5. Context</h2>
<h3 id="理解">理解</h3>
<blockquote>
<p>一种组件间通信方式, 常用于【祖组件】与【后代组件】间通信</p>
</blockquote>
<h3 id="使用-1">使用</h3>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="mi">1</span><span class="p">)</span> <span class="nx">创建Context容器对象</span><span class="err">：</span>
	<span class="kr">const</span> <span class="nx">XxxContext</span> <span class="o">=</span> <span class="nx">React</span><span class="p">.</span><span class="nx">createContext</span><span class="p">()</span>  
	
<span class="mi">2</span><span class="p">)</span> <span class="nx">渲染子组时</span><span class="err">，</span><span class="nx">外面包裹xxxContext</span><span class="p">.</span><span class="nx">Provider</span><span class="p">,</span> <span class="nx">通过value属性给后代组件传递数据</span><span class="err">：</span>
	<span class="o">&lt;</span><span class="nx">xxxContext</span><span class="p">.</span><span class="nx">Provider</span> <span class="nx">value</span><span class="o">=</span><span class="p">{</span><span class="nx">数据</span><span class="p">}</span><span class="o">&gt;</span>
		<span class="nx">子组件</span>
    <span class="o">&lt;</span><span class="err">/xxxContext.Provider&gt;</span>
    
<span class="mi">3</span><span class="p">)</span> <span class="nx">后代组件读取数据</span><span class="err">：</span>

	<span class="c1">//第一种方式:仅适用于类组件 
</span><span class="c1"></span>	  <span class="kr">static</span> <span class="nx">contextType</span> <span class="o">=</span> <span class="nx">xxxContext</span>  <span class="c1">// 声明接收context
</span><span class="c1"></span>	  <span class="k">this</span><span class="p">.</span><span class="nx">context</span> <span class="c1">// 读取context中的value数据
</span><span class="c1"></span>	  
	<span class="c1">//第二种方式: 函数组件与类组件都可以
</span><span class="c1"></span>	  <span class="o">&lt;</span><span class="nx">xxxContext</span><span class="p">.</span><span class="nx">Consumer</span><span class="o">&gt;</span>
	    <span class="p">{</span>
	      <span class="nx">value</span> <span class="p">=&gt;</span> <span class="p">(</span> <span class="c1">// value就是context中的value数据
</span><span class="c1"></span>	        <span class="nx">要显示的内容</span>
	      <span class="p">)</span>
	    <span class="p">}</span>
	  <span class="o">&lt;</span><span class="err">/xxxContext.Consumer&gt;</span>
</code></pre></td></tr></table>
</div>
</div><h3 id="注意">注意</h3>
<pre><code>在应用开发中一般不用context, 一般都用它的封装react插件
</code></pre>
<hr/>
<h2 id="6-组件优化">6. 组件优化</h2>
<h3 id="component的2个问题">Component的2个问题</h3>
<blockquote>
<ol>
<li>
<p>只要执行setState(),即使不改变状态数据, 组件也会重新render() ==&gt; 效率低</p>
</li>
<li>
<p>只当前组件重新render(), 就会自动重新render子组件，纵使子组件没有用到父组件的任何数据 ==&gt; 效率低</p>
</li>
</ol>
</blockquote>
<h3 id="效率高的做法">效率高的做法</h3>
<blockquote>
<p>只有当组件的state或props数据发生改变时才重新render()</p>
</blockquote>
<h3 id="原因">原因</h3>
<blockquote>
<p>Component中的shouldComponentUpdate()总是返回true</p>
</blockquote>
<h3 id="解决">解决</h3>
<pre><code>办法1: 
	重写shouldComponentUpdate()方法
	比较新旧state或props数据, 如果有变化才返回true, 如果没有返回false
办法2:  
	使用PureComponent
	PureComponent重写了shouldComponentUpdate(), 只有state或props数据有变化才返回true
	注意: 
		只是进行state和props数据的浅比较, 如果只是数据对象内部数据变了, 返回false  
		不要直接修改state数据, 而是要产生新数据
项目中一般使用PureComponent来优化
</code></pre>
<hr/>
<h2 id="7-render-props">7. render props</h2>
<p><img
        class="lazyload"
        src="/svg/loading.min.svg"
        data-src="https://raw.githubusercontent.com/yzuxqz/pic-bed/master/notes-img/renderprops.png"
        data-srcset="https://raw.githubusercontent.com/yzuxqz/pic-bed/master/notes-img/renderprops.png, https://raw.githubusercontent.com/yzuxqz/pic-bed/master/notes-img/renderprops.png 1.5x, https://raw.githubusercontent.com/yzuxqz/pic-bed/master/notes-img/renderprops.png 2x"
        data-sizes="auto"
        alt="https://raw.githubusercontent.com/yzuxqz/pic-bed/master/notes-img/renderprops.png"
        title="https://raw.githubusercontent.com/yzuxqz/pic-bed/master/notes-img/renderprops.png" /></p>
<h3 id="如何向组件内部动态传入带内容的结构标签">如何向组件内部动态传入带内容的结构(标签)?</h3>
<pre><code>Vue中: 
	使用slot技术, 也就是通过组件标签体传入结构  &lt;A&gt;&lt;B/&gt;&lt;/A&gt;
React中:
	使用children props: 通过组件标签体传入结构
	使用render props: 通过组件标签属性传入结构,而且可以携带数据，一般用render函数属性
</code></pre>
<h3 id="children-props">children props</h3>
<pre><code>&lt;A&gt;
  &lt;B&gt;xxxx&lt;/B&gt;
&lt;/A&gt;
{this.props.children}
问题: 如果B组件需要A组件内的数据, ==&gt; 做不到 
</code></pre>
<h3 id="render-props">render props</h3>
<pre><code>&lt;A render={(data) =&gt; &lt;C data={data}&gt;&lt;/C&gt;}&gt;&lt;/A&gt;
A组件: {this.props.render(内部state数据)}
C组件: 读取A组件传入的数据显示 {this.props.data} 
</code></pre>
<hr/>
<h2 id="8-错误边界">8. 错误边界</h2>
<h4 id="理解-1">理解：</h4>
<p>错误边界(Error boundary)：用来捕获后代组件错误，渲染出备用页面</p>
<h4 id="特点">特点：</h4>
<p>只能捕获后代组件生命周期产生的错误，不能捕获自己组件产生的错误和其他组件在合成事件、定时器中产生的错误</p>
<h5 id="使用方式">使用方式：</h5>
<p>getDerivedStateFromError配合componentDidCatch</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="c1">// 生命周期函数，一旦后台组件报错，就会触发
</span><span class="c1"></span><span class="kr">static</span> <span class="nx">getDerivedStateFromError</span><span class="p">(</span><span class="nx">error</span><span class="p">)</span> <span class="p">{</span>
    <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">error</span><span class="p">);</span>
    <span class="c1">// 在render之前触发
</span><span class="c1"></span>    <span class="c1">// 返回新的state
</span><span class="c1"></span>    <span class="k">return</span> <span class="p">{</span>
        <span class="nx">hasError</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span>
    <span class="p">};</span>
<span class="p">}</span>

<span class="nx">componentDidCatch</span><span class="p">(</span><span class="nx">error</span><span class="p">,</span> <span class="nx">info</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">// 统计页面的错误。发送请求发送到后台去
</span><span class="c1"></span>    <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">error</span><span class="p">,</span> <span class="nx">info</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></td></tr></table>
</div>
</div><h2 id="9-组件通信方式总结">9. 组件通信方式总结</h2>
<h4 id="组件间的关系">组件间的关系：</h4>
<ul>
<li>父子组件</li>
<li>兄弟组件（非嵌套组件）</li>
<li>祖孙组件（跨级组件）</li>
</ul>
<h4 id="几种通信方式">几种通信方式：</h4>
<pre><code>	1.props：
		(1).children props
		(2).render props
	2.消息订阅-发布：
		pubs-sub、event等等
	3.集中式管理：
		redux、dva等等
	4.conText:
		生产者-消费者模式
</code></pre>
<h4 id="比较好的搭配方式">比较好的搭配方式：</h4>
<pre><code>	父子组件：props
	兄弟组件：消息订阅-发布、集中式管理
	祖孙组件(跨级组件)：消息订阅-发布、集中式管理、conText(开发用的少，封装插件用的多)
</code></pre>
</div><div class="post-footer" id="post-footer">
    <div class="post-info">
        <div class="post-info-line">
            <div class="post-info-mod">
                <span>更新于 2021-09-02</span>
            </div>
            <div class="post-info-license"></div>
        </div>
        <div class="post-info-line">
            <div class="post-info-md"><span>
                            <a class="link-to-markdown" href="/posts/react%E6%89%A9%E5%B1%95/index.md" target="_blank">阅读原始文档</a>
                        </span></div>
            <div class="post-info-share">
                <span><a href="javascript:void(0);" title="分享到 Twitter" data-sharer="twitter" data-url="http://example.org/posts/react%E6%89%A9%E5%B1%95/" data-title="react扩展" data-via="xxxx" data-hashtags="react,react优化"><i class="fab fa-twitter fa-fw"></i></a><a href="javascript:void(0);" title="分享到 Facebook" data-sharer="facebook" data-url="http://example.org/posts/react%E6%89%A9%E5%B1%95/" data-hashtag="react"><i class="fab fa-facebook-square fa-fw"></i></a><a href="javascript:void(0);" title="分享到 WhatsApp" data-sharer="whatsapp" data-url="http://example.org/posts/react%E6%89%A9%E5%B1%95/" data-title="react扩展" data-web><i class="fab fa-whatsapp fa-fw"></i></a><a href="javascript:void(0);" title="分享到 Line" data-sharer="line" data-url="http://example.org/posts/react%E6%89%A9%E5%B1%95/" data-title="react扩展"><i data-svg-src="/lib/simple-icons/icons/line.min.svg"></i></a><a href="javascript:void(0);" title="分享到 微博" data-sharer="weibo" data-url="http://example.org/posts/react%E6%89%A9%E5%B1%95/" data-title="react扩展"><i class="fab fa-weibo fa-fw"></i></a><a href="javascript:void(0);" title="分享到 Myspace" data-sharer="myspace" data-url="http://example.org/posts/react%E6%89%A9%E5%B1%95/" data-title="react扩展" data-description=""><i data-svg-src="/lib/simple-icons/icons/myspace.min.svg"></i></a><a href="javascript:void(0);" title="分享到 Blogger" data-sharer="blogger" data-url="http://example.org/posts/react%E6%89%A9%E5%B1%95/" data-title="react扩展" data-description=""><i class="fab fa-blogger fa-fw"></i></a><a href="javascript:void(0);" title="分享到 Evernote" data-sharer="evernote" data-url="http://example.org/posts/react%E6%89%A9%E5%B1%95/" data-title="react扩展"><i class="fab fa-evernote fa-fw"></i></a></span>
            </div>
        </div>
    </div>

    <div class="post-info-more">
        <section class="post-tags"><i class="fas fa-tags fa-fw"></i>&nbsp;<a href="/tags/react/">react</a>,&nbsp;<a href="/tags/react%E4%BC%98%E5%8C%96/">react优化</a></section>
        <section>
            <span><a href="javascript:void(0);" onclick="window.history.back();">返回</a></span>&nbsp;|&nbsp;<span><a href="/">主页</a></span>
        </section>
    </div>

    <div class="post-nav"><a href="/posts/reacthooks/" class="prev" rel="prev" title="hooks"><i class="fas fa-angle-left fa-fw"></i>hooks</a>
            <a href="/posts/first_post/" class="next" rel="next" title="想要和我一样吗？">想要和我一样吗？<i class="fas fa-angle-right fa-fw"></i></a></div>
</div>
<div id="comments"></div></article></div>
            </main><footer class="footer">
        <div class="footer-container"><div class="footer-line">由 <a href="https://gohugo.io/" target="_blank" rel="noopener noreffer" title="Hugo 0.89.1">Hugo</a> 强力驱动 | 主题 - <a href="https://github.com/dillonzq/LoveIt" target="_blank" rel="noopener noreffer" title="LoveIt 0.2.10"><i class="far fa-kiss-wink-heart fa-fw"></i> LoveIt</a>
                </div><div class="footer-line"><i class="far fa-copyright fa-fw"></i><span itemprop="copyrightYear">2021</span><span class="author" itemprop="copyrightHolder">&nbsp;<a href="https://github.com/yzuxqz" target="_blank">yzuxqz</a></span></div>
        </div>
    </footer></div>

        <div id="fixed-buttons"><a href="#" id="back-to-top" class="fixed-button" title="回到顶部">
                <i class="fas fa-arrow-up fa-fw"></i>
            </a><a href="#" id="view-comments" class="fixed-button" title="查看评论">
                <i class="fas fa-comment fa-fw"></i>
            </a>
        </div><link rel="stylesheet" href="/lib/katex/katex.min.css"><link rel="stylesheet" href="/lib/katex/copy-tex.min.css"><script type="text/javascript" src="/lib/smooth-scroll/smooth-scroll.min.js"></script><script type="text/javascript" src="/lib/lazysizes/lazysizes.min.js"></script><script type="text/javascript" src="/lib/clipboard/clipboard.min.js"></script><script type="text/javascript" src="/lib/sharer/sharer.min.js"></script><script type="text/javascript" src="/lib/katex/katex.min.js"></script><script type="text/javascript" src="/lib/katex/auto-render.min.js"></script><script type="text/javascript" src="/lib/katex/copy-tex.min.js"></script><script type="text/javascript" src="/lib/katex/mhchem.min.js"></script><script type="text/javascript">window.config={"code":{"copyTitle":"复制到剪贴板","maxShownLines":10},"comment":{},"math":{"delimiters":[{"display":true,"left":"$$","right":"$$"},{"display":true,"left":"\\[","right":"\\]"},{"display":false,"left":"$","right":"$"},{"display":false,"left":"\\(","right":"\\)"}],"strict":false}};</script><script type="text/javascript" src="/js/theme.min.js"></script></body>
</html>
